/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * CodeFrame.java
 *
 * Created on 17/12/2011, 14:03:41
 */
package codebar;

import java.awt.Font;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultListModel;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

/**
 *
 * @author yole
 */
public class CodeFrame extends javax.swing.JFrame {

    private String cod;
    private boolean state;
    private Thread block;
    private ArrayList<String> lbInserted;
    private ArrayList<String> lbRemoved;
    private CodeList codeList;
    private String forum;
    private String vara;
    private ConfigFrame frame;
    
    /** Creates new form CodeFrame */
    public CodeFrame(String forum, String vara) {
        initComponents();
        this.vara = vara;
        this.forum = forum;
        cod = new String("");
        lbInserted = new ArrayList<String>();
        lbRemoved = new ArrayList<String>();
        codeList = new CodeList();
        state = false;
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setResizable(false);
        CodeAction act = new CodeAction();
        jtbtDigit.addItemListener(act);
        jbtSend.addActionListener(act);
        jbtDelete.addActionListener(act);
        jmnitClose.addActionListener(act);
        jmnitExport.addActionListener(act);
        jmnitConfig.addActionListener(act);
        jbtExport.addActionListener(act);
        jbtImport.addActionListener(act);
        jbtRegister.addActionListener(act);
        jmnitImport.addActionListener(act);
        jmnitRegister.addActionListener(act);
        jmnitRmImport.addActionListener(act);
        setDigitPanelShow(false);
        requestFocus();
        setFocusable(true);
        KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        manager.addKeyEventDispatcher(new MyDispatcher());
        frame = new ConfigFrame(this);
    }
    
    public void setVara(String vara) {
        this.vara = vara;
    }
    
    public void setForum(String forum) {
        this.forum = forum;
    }
    
    public CodeList getCodeList() {
        return codeList;
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jtxaNOrdem = new javax.swing.JTextArea();
        jtxtAno = new javax.swing.JTextField();
        jlbAno = new javax.swing.JLabel();
        jlbProc = new javax.swing.JLabel();
        jtxtNroProc = new javax.swing.JTextField();
        jbtSend = new javax.swing.JButton();
        jtbtDigit = new javax.swing.JToggleButton();
        jbtDelete = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        jlstCod = new javax.swing.JList();
        jbtExport = new javax.swing.JButton();
        jbtImport = new javax.swing.JButton();
        jbtRegister = new javax.swing.JButton();
        jmnMain = new javax.swing.JMenuBar();
        jmnOp = new javax.swing.JMenu();
        jmnitRmImport = new javax.swing.JMenuItem();
        jmnitConfig = new javax.swing.JMenuItem();
        jmnitExport = new javax.swing.JMenuItem();
        jmnitImport = new javax.swing.JMenuItem();
        jmnitRegister = new javax.swing.JMenuItem();
        jmnitClose = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jtxaNOrdem.setColumns(20);
        jtxaNOrdem.setEditable(false);
        jtxaNOrdem.setRows(5);
        jScrollPane1.setViewportView(jtxaNOrdem);

        jlbAno.setText("Ano");

        jlbProc.setText("Nr. do processo");

        jbtSend.setText("Enviar");

        jtbtDigit.setText("Digitar informações");

        jbtDelete.setText("Remover último");

        jlstCod.setFont(new java.awt.Font("Arial", 0, 24)); // NOI18N
        jlstCod.setEnabled(false);
        jScrollPane2.setViewportView(jlstCod);

        jbtExport.setText("Exportar");

        jbtImport.setText("Importar");

        jbtRegister.setText("Registrar");

        jmnOp.setText("Opções");

        jmnitRmImport.setText("Remover Importação");
        jmnOp.add(jmnitRmImport);

        jmnitConfig.setText("Configurar forum e vara");
        jmnOp.add(jmnitConfig);

        jmnitExport.setText("Exportar");
        jmnOp.add(jmnitExport);

        jmnitImport.setText("Importar");
        jmnitImport.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jmnitImportActionPerformed(evt);
            }
        });
        jmnOp.add(jmnitImport);

        jmnitRegister.setText("Registrar");
        jmnOp.add(jmnitRegister);

        jmnitClose.setText("Fechar");
        jmnOp.add(jmnitClose);

        jmnMain.add(jmnOp);

        setJMenuBar(jmnMain);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jbtDelete, javax.swing.GroupLayout.PREFERRED_SIZE, 179, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbtRegister, javax.swing.GroupLayout.PREFERRED_SIZE, 157, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 395, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jbtSend, javax.swing.GroupLayout.PREFERRED_SIZE, 96, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jlbAno, javax.swing.GroupLayout.PREFERRED_SIZE, 91, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jlbProc)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                        .addComponent(jtxtNroProc, javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jtxtAno, javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jtbtDigit, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jbtExport, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbtImport, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addContainerGap())
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 657, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jtbtDigit)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jlbAno)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jtxtAno, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jlbProc)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jtxtNroProc, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbtSend))
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 213, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jbtDelete)
                    .addComponent(jbtExport)
                    .addComponent(jbtImport)
                    .addComponent(jbtRegister))
                .addGap(18, 18, 18)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 249, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jmnitImportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jmnitImportActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_jmnitImportActionPerformed

    /**
     * @param args the command line arguments
     */
//    public static void main(String args[]) {
//        /* Set the Nimbus look and feel */
//        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
//        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
//         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
//         */
//        try {
//            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
//                if ("Nimbus".equals(info.getName())) {
//                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
//                    break;
//                }
//            }
//        } catch (ClassNotFoundException ex) {
//            java.util.logging.Logger.getLogger(CodeFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
//        } catch (InstantiationException ex) {
//            java.util.logging.Logger.getLogger(CodeFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
//        } catch (IllegalAccessException ex) {
//            java.util.logging.Logger.getLogger(CodeFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
//        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
//            java.util.logging.Logger.getLogger(CodeFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
//        }
//        //</editor-fold>
//
//        /* Create and display the form */
//        java.awt.EventQueue.invokeLater(new Runnable() {
//
//            public void run() {
//                new CodeFrame().setVisible(true);
//            }
//        });
//    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JButton jbtDelete;
    private javax.swing.JButton jbtExport;
    private javax.swing.JButton jbtImport;
    private javax.swing.JButton jbtRegister;
    private javax.swing.JButton jbtSend;
    private javax.swing.JLabel jlbAno;
    private javax.swing.JLabel jlbProc;
    private javax.swing.JList jlstCod;
    private javax.swing.JMenuBar jmnMain;
    private javax.swing.JMenu jmnOp;
    private javax.swing.JMenuItem jmnitClose;
    private javax.swing.JMenuItem jmnitConfig;
    private javax.swing.JMenuItem jmnitExport;
    private javax.swing.JMenuItem jmnitImport;
    private javax.swing.JMenuItem jmnitRegister;
    private javax.swing.JMenuItem jmnitRmImport;
    private javax.swing.JToggleButton jtbtDigit;
    private javax.swing.JTextArea jtxaNOrdem;
    private javax.swing.JTextField jtxtAno;
    private javax.swing.JTextField jtxtNroProc;
    // End of variables declaration//GEN-END:variables

    private class MyDispatcher implements KeyEventDispatcher {
        @Override
        public boolean dispatchKeyEvent(KeyEvent e) {
            if (e.getID() == KeyEvent.KEY_TYPED) {
                if (!state) {
                        if ((int)e.getKeyChar() >= 48 && (int)e.getKeyChar() <= 57)
                            cod += e.getKeyChar();
                        if (cod.length() == 20) {
                                try {
                                    String year = Utils.extract(Utils.Type.YEAR, forum, cod);
                                    String nordem = Utils.extract(Utils.Type.NORDEM, forum, cod);
                                    codeList.add(year, nordem);
                                    lbInserted.add(cod);
                                    setRegisterContent();
                                    setCodLabel();
                                    if (!isValidSerial(cod)) {
                                        JOptionPane.showMessageDialog(null, "Código inválido. Remova o último registro.");
                                    }
                                } catch (DuplicatedDataException ex) {
                                    JOptionPane.showMessageDialog(null, "Dado já existente.");
                                } finally {
                                    cod = "";
                                }
                        }
                    
                }
            }
            return false;
            }
        }

    class CodeAction implements ActionListener, ItemListener {
        
        
        public void actionPerformed(ActionEvent e) {
            
            if ( e.getSource() == jbtSend) {
                try {
                    String ano = jtxtAno.getText();
                    String proc = jtxtNroProc.getText();
                    if (proc.length() < 7 && ano.length() == 4 && Utils.isNumber(ano) && Utils.isNumber(proc)) {
                        String zero = "";
                        for (int i = 0; i < 6 - proc.length(); i++)
                            zero += "0";
                        cod = forum+vara+ano+zero+proc+"000000";
                        jtxtAno.setText("");
                        jtxtNroProc.setText("");
                        lbInserted.add(cod);
                        codeList.add(ano, zero+proc);
                        setCodLabel();
                        setRegisterContent();
                        cod = "";
                    }
                    else {
                        JOptionPane.showMessageDialog(null, "Valores de ano e/ou processo inválidos.");
                    }
                } catch (DuplicatedDataException ex) {
                    JOptionPane.showMessageDialog(null, "Dado já existente.");
                }
            }
            
            if (e.getSource() == jbtDelete) {
                try {
                    cod = "";
                    lbRemoved.add(lbInserted.get(lbInserted.size()-1));
                    String cod = lbInserted.get(lbInserted.size()-1);
                    String year = Utils.extract(Utils.Type.YEAR, forum, cod);
                    String nordem = Utils.extract(Utils.Type.NORDEM, forum, cod);
                    codeList.remove(year, nordem);
                    lbInserted.remove(lbInserted.size()-1);
                    setCodLabel();
                    setRegisterContent();
                } catch (NotFoundException ex) {
                   JOptionPane.showMessageDialog(null, ex.getException());
                }
            }
            
            if (e.getSource() == jbtImport) {
                Utils.importFile(codeList);
                setRegisterContent();
            }
            
            if (e.getSource() == jbtRegister) {
                YearTable yTable = new YearTable(codeList);
                yTable.setVisible(true);
            }
            
            if (e.getSource() == jmnitConfig) {
                frame.setVisible(true);
            }
            
            if (e.getSource() == jmnitExport) {
                Utils.export(jtxaNOrdem.getText());
            }
            
            if (e.getSource() == jmnitClose) {
                dispose();
            }
            
            if (e.getSource() == jbtExport) {
                Utils.export(jtxaNOrdem.getText());
            }
            
            if (e.getSource() == jmnitRegister) {
                YearTable yTable = new YearTable(codeList);
                yTable.setVisible(true);
            }
            
            if (e.getSource() == jmnitImport) {
                Utils.importFile(codeList);
                setRegisterContent();
            }
            
            if (e.getSource() == jmnitRmImport) {
                codeList.clear();
                setRegisterContent();
            }
            
        }
        
        public void itemStateChanged(ItemEvent e) {
            
            if (e.getSource() == jtbtDigit) {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    setDigitPanelShow(true);
                    state = true;
                    cod = "";
                }
                else {
                    setDigitPanelShow(false);
                    state = false;
                    cod = "";
                }
            }
            
        }
        
    }
    
    public void setDigitPanelShow(boolean opt) {
        jtxtAno.setVisible(opt);
        jtxtNroProc.setVisible(opt);
        jbtSend.setVisible(opt);
        jlbAno.setVisible(opt);
        jlbProc.setVisible(opt);
    }
    
    public boolean isValidSerial(String s) {
        
        String ano = Utils.extract(Utils.Type.YEAR, this.forum, s);
        String vara = Utils.extract(Utils.Type.VARA, this.forum, s);
        String forum = Utils.extract(Utils.Type.FORUM, this.forum, s);
        Calendar cal = Calendar.getInstance();
        int anoatual = cal.get(Calendar.YEAR);
        
        if ( Integer.valueOf(ano)  > (anoatual - 100) && Integer.valueOf(ano) < (anoatual + 100)
                && vara.compareTo(this.vara) == 0 && forum.compareTo(this.forum) == 0 )
            return true;
        else
            return false;
        
    }
    

    
    public void setCodLabel() {
        String cod;
        String year;
        DefaultListModel model = new DefaultListModel();
        int i;
        for ( i = 0; i < lbInserted.size(); i++ ) {
            cod = Utils.extract(Utils.Type.NORDEM, forum, lbInserted.get(i));
            year = Utils.extract(Utils.Type.YEAR, forum, lbInserted.get(i));
            model.addElement(cod + "/" + year);
        }

        jlstCod.setModel(model);
        int lastIndex = jlstCod.getModel().getSize() - 1;
        if (lastIndex >= 0) {
        jlstCod.ensureIndexIsVisible(lastIndex);
}
    }
    
    public void setRegisterContent() {
        jtxaNOrdem.setText("#T " + codeList.total() + "\n");
        
        for (int i = 0; i < codeList.size(); i++) {
            jtxaNOrdem.append("\nA " + codeList.getYear(i)+"\n# " 
                    + codeList.get(i).size() + "\n");
            for (int j = 0; j < codeList.get(i).size(); j++) {
                jtxaNOrdem.append("P " + codeList.get(i).getNOrdem(j) + "\n");
            }
        }
        
    }
    
    public void clearBuffer() {
        cod = "";
    }

}
